/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using DataModelException = System.Qizx.Api.DataModelException;
using QName = System.Qizx.Api.QName;
using XMLPushStream = System.Qizx.Api.XMLPushStream;
using XMLSerializer = System.Qizx.Api.Util.XMLSerializer;
using Utils = System.Qizx.Util.Basic.Utils;
using IQName = System.Qizx.Xdm.IQName;
using Expression = System.Qizx.XQuery.Op.Expression;
namespace System.Qizx.XQuery
{
	
	/// <summary> Displays a compiled expression as a XML document. 
	/// This is NOT a XQueryX generator! (we'll rather use a Visitor)
	/// </summary>
	public class XMLExprDisplay:ExprDisplay
	{
		virtual public XMLPushStream Output
		{
			get
			{
				return out_Renamed;
			}
			
			set
			{
				this.out_Renamed = value;
			}
			
		}
		private XMLPushStream out_Renamed;
		private System.Collections.ArrayList nameStack = new System.Collections.ArrayList();
		private bool displayTypes = true;
		private bool displayFlags = true;
		
		public XMLExprDisplay(XMLPushStream output)
		{
			this.out_Renamed = output;
		}
		
		public XMLExprDisplay()
		{
			System.IO.StreamWriter temp_writer;
			temp_writer = new System.IO.StreamWriter(System.Console.OpenStandardError(), System.Text.Encoding.Default);
			temp_writer.AutoFlush = true;
			XMLSerializer ser = new XMLSerializer(temp_writer);
			ser.Indent = 2;
			out_Renamed = ser;
		}
		
		// @see System.Qizx.XQuery.XDisplay#header(System.Qizx.Api.QName)
		public override void  header(QName name)
		{
			nameStack.Add(name);
			try
			{
				out_Renamed.putElementStart(name);
			}
			catch (DataModelException e)
			{
				SupportClass.WriteStackTrace(e, Console.Error);
			}
		}
		
		// @see System.Qizx.XQuery.XDisplay#header(java.lang.String)
		public override void  header(string name)
		{
			header(IQName.GetQName(name));
		}
		
		// @see System.Qizx.XQuery.XDisplay#header(System.Qizx.XQuery.Op.Expression)
		public override void  header(Expression expr)
		{
			QName name = IQName.GetQName(Utils.shortClassName(expr.GetType()));
			header(name);
			headerInfo(expr);
		}
		
		public override void  headerInfo(Expression expr)
		{
			// flags etc
			if (displayTypes)
				property("type", expr.getType());
			int flags = expr.Flags;
			if (displayFlags && flags != 0)
			{
				System.Text.StringBuilder b = new System.Text.StringBuilder();
				if ((flags & Expression.UNORDERED) != 0)
					b.Append("Un,");
				if ((flags & Expression.DOCUMENT_ORDER) != 0)
					b.Append("DO,");
				if ((flags & Expression.SAME_DEPTH) != 0)
					b.Append("=D,");
				if ((flags & Expression.CONSTANT) != 0)
					b.Append("Cst,");
				if ((flags & Expression.NUMERIC) != 0)
					b.Append("Nu,");
				if ((flags & Expression.UPDATING) != 0)
					b.Append("Up,");
				if ((flags & Expression.WITHIN_NODE) != 0)
					b.Append("inN,");
				if ((flags & Expression.WITHIN_SUBTREE) != 0)
					b.Append("inT,");
				property("flags", b.ToString());
			}
		}
		
		// @see System.Qizx.XQuery.XDisplay#end()
		public override void  end()
		{
			System.Object tempObject;
			tempObject = nameStack[nameStack.Count - 1];
			nameStack.RemoveAt(nameStack.Count - 1);
			QName name = (QName) tempObject;
			try
			{
				out_Renamed.putElementEnd(name);
			}
			catch (DataModelException e)
			{
				reportError(e);
			}
		}
		
		// @see System.Qizx.XQuery.XDisplay#property(java.lang.String, java.lang.String)
		public override void  property(string prop, string value_Renamed)
		{
			try
			{
				if (value_Renamed == null)
					value_Renamed = "<null>";
				out_Renamed.putAttribute(IQName.GetQName(prop), value_Renamed, null);
			}
			catch (DataModelException e)
			{
				reportError(e);
			}
		}
		
		public override void  property(string prop, XQType targetType)
		{
			if (targetType != null)
			{
				property(prop, targetType.ToString());
			}
		}
		
		// wrapped Child expression
		public override void  child(string role, Expression expr)
		{
			QName roleName = IQName.GetQName(role);
			try
			{
				out_Renamed.putElementStart(roleName);
				child(expr);
				out_Renamed.putElementEnd(roleName);
			}
			catch (DataModelException e)
			{
				reportError(e);
			}
		}
		
		public override void  children(string role, Expression[] args)
		{
			QName roleName = IQName.GetQName(role);
			try
			{
				out_Renamed.putElementStart(roleName);
				children(args);
				out_Renamed.putElementEnd(roleName);
			}
			catch (DataModelException e)
			{
				reportError(e);
			}
		}
		
		// pseudo Child
		public override void  child(string role, string value_Renamed)
		{
			QName roleName = IQName.GetQName(role);
			try
			{
				out_Renamed.putElementStart(roleName);
				out_Renamed.putText(value_Renamed);
				out_Renamed.putElementEnd(roleName);
			}
			catch (DataModelException e)
			{
				reportError(e);
			}
		}
		
		
		private void  reportError(DataModelException e)
		{
			SupportClass.WriteStackTrace(e, Console.Error);
		}
		
		public override void  flush()
		{
			out_Renamed.flush();
		}
	}
}